package com.moogene.android.engine.animlite;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;

public class FrameAnim extends Anime{

	private String TAG = "FrameAnim";

	Bitmap mImage;

	int mWidth;
	int mHeight;
	int mRow;
	int mColumn;
	private int mNumOfTotalFrame;
	private boolean mIsInfinite;
	private int mFrames[];
	private int mCurFrame;
	private int mNumOfFrame;

	//	private Rect mSrc;

//	public FrameAnim(int id) {
//		this(BitmapFactory.decodeResource(InfoMediator.getResHandler(), id));
//		setSourceAline(1, 1);
//	}
//
//	public FrameAnim(int id, int row, int column) {
//        this(BitmapFactory.decodeResource(InfoMediator.getResHandler(), id));
//        setSourceAline(row, column);
//    }

	FrameAnim(Bitmap img, DrawableWrapper drawableWrapper, int row, int column) {
		super(drawableWrapper);
		mImage = img;
		setSourceAline(row, column);
	}
	
	private void updateDrawableImage(){
		int row = mFrames[mCurFrame] / mColumn;
		int col = mFrames[mCurFrame] % mColumn;
		setDrawableImage(row, col);
	}

	private void setDrawableImage(int rowID, int colID) {
		int x = mWidth * colID;
		int y = mHeight * rowID;
		Bitmap tmp = Bitmap.createBitmap(mImage, x, y, mWidth, mHeight);
		drawableWrapper.setBitmap(tmp);
	}

	private void setSourceAline(int row, int column) {
		if (row <= 0 || column <= 0) {
			Log.d(TAG, "setSourceAline() param is illegal; row = " + row
					+ "; col = " + column);
			throw new IllegalArgumentException();
		}

		int width = mImage.getWidth();
		int height = mImage.getHeight();
		if (width % column != 0) {
			Log.d(TAG, "setSourceAline() param is illegal; row = " + row);
			throw new IllegalArgumentException();
		}
		if (height % row != 0) {
			Log.d(TAG, "setSourceAline() param is illegal; height = " + column);
			throw new IllegalArgumentException();
		}
		mRow = row;
		mColumn = column;
		mWidth = width / column;
		mHeight = height / row;
		mNumOfTotalFrame = mRow * mColumn;
		setDrawableImage(0, 0);
	}

	public void setFrameSize(int width, int height) {
		if (width <= 0 || height <= 0) {
			Log.d(TAG, "setFrameSize() param is illegal; width = " + width
					+ "; height = " + height);
			throw new IllegalArgumentException();
		}
		int widthTotal = mImage.getWidth();
		int heightTotal = mImage.getHeight();
		if (widthTotal % width != 0) {
			Log.d(TAG, "setFrameSize() param is illegal; row = " + width);
			throw new IllegalArgumentException();
		}
		if (heightTotal % height != 0) {
			Log.d(TAG, "setFrameSize() param is illegal; height = " + height);
			throw new IllegalArgumentException();
		}
		mRow = heightTotal / height;
		mColumn = widthTotal / width;
		mWidth = width;
		mHeight = height;
		mNumOfTotalFrame = mRow * mColumn;
		setDrawableImage(0, 0);
	}

	public void start(int begin, int end) {
		if (begin > mNumOfTotalFrame - 1 || begin < 0 || end > mNumOfTotalFrame
				|| end < 0) {
			Log.d(TAG, "start(); begin, end Param is illegal");
			throw new IllegalArgumentException();
		}
		start();
		if (end > begin) {
			mNumOfFrame = end - begin;
		} else {
			mNumOfFrame = end - begin + mNumOfTotalFrame;
		}
		mCurFrame = -1;
		mFrames = new int[mNumOfFrame];
		for (int i = 0; i < mNumOfFrame; i++) {
			mFrames[i] = (i + begin) % mNumOfTotalFrame;
		}
		nextFrame();
	}

	public void start(int[] frames) {
		int len = frames.length;
		for (int i = 0; i < len; i++) {
			if (frames[i] > mNumOfTotalFrame - 1 || frames[i] < 0) {
				Log.d(TAG, "start(); frames[] Param is illegal");
				throw new IllegalArgumentException();
			}
		}
		start();
		mCurFrame = -1;
		mFrames = frames;
		mNumOfFrame = len;
		nextFrame();
	}

	@Override
	public void stop() {
		super.stop();
		drawableWrapper.setBitmap(null);
	}

	public void setInfinite(boolean isOneShot) {
		mIsInfinite = isOneShot;
	}

	public void setFrame(int frameID) {
		mFrames = new int[1];
		mFrames[0] = frameID;
		mCurFrame = 0;
		updateDrawableImage();
		pause();
	}

	boolean nextFrame() {
		if (!super.nextFrame()) {
			return false;
		}
		if (mNumOfFrame == 1) {
			mCurFrame = 0;
		} else {
			mCurFrame++;
			if (mCurFrame >= mNumOfFrame) {
				if (!mIsInfinite) {
					pause();
					return false;
				} else {
					mCurFrame = 0;
				}
			}
		}
		updateDrawableImage();
		if (mNumOfFrame == 1) {
			return false;
		} else {
			return true;
		}
	}

	public void drawFrame(Canvas canvas, int left, int top, int frameID) {
		int row = frameID / mColumn;
		int col = frameID % mColumn;
		Rect src = new Rect(col * mWidth, row * mHeight, col * mWidth + mWidth,
				row * mHeight + mHeight);
		Rect dest = new Rect(left, top, left + mWidth, top + mHeight);
		canvas.drawBitmap(mImage, src, dest, null);
	}
	
	public Bitmap getPreview(int frameId){
		if(frameId >= mNumOfTotalFrame){
			throw new IllegalArgumentException("frameId :" + frameId + " is out of scope (" + mNumOfTotalFrame + ")");
		}
		int row = frameId / mColumn;
		int col = frameId % mColumn;
		int x = mWidth * col;
		int y = mHeight * row;
		return Bitmap.createBitmap(mImage, x, y, mWidth, mHeight);
	}

//	Rect getDstRect(int left, int top) {
//		Rect dest = new Rect(left - mAnchorX, top - mAnchorY, left + mWidth
//				- mAnchorX, top + mHeight - mAnchorY);
//		return dest;
//	}

}
